package com.alstudio.utils.android.net.http.http2;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.params.HttpParams;

import android.net.http.AndroidHttpClient;
import android.text.TextUtils;

import com.alstudio.utils.android.ALFileManager;

public class HttpDownloadRequest {

	public static final String TAG = HttpDownloadRequest.class.getSimpleName();

	private static final int BUFFER_SIZE = 512;

	private String url;
	private String filePath;
	private long fileSize = 0;
	private HttpParameters params = null;
	private HttpParameters headers = null;
	private AndroidHttpClient client;
	private HttpGet getMethod;
	private boolean isInterrupted = false;

	public HttpDownloadRequest(String url, String filePath) {
		this.url = url;
		this.filePath = filePath;
	}

	public void setHeader(HttpParameters headers) {
		this.headers = headers;
	}

	public void setParameter(HttpParameters params) {
		this.params = params;
	}

	public void addHeader(String name, String value) {
		if (headers == null)
			headers = new HttpParameters();

		headers.add(name, value);
	}

	public void addParameter(String name, String value) {
		if (params == null)
			params = new HttpParameters();

		params.add(name, value);
	}

	public boolean request(IHttpProgressHandler handler) {
		if (TextUtils.isEmpty(url))
			return false;

		String param = "";
		if (params != null) {
			param = URLEncodedUtils.format(params.value(), "UTF-8");
			if (!TextUtils.isEmpty(param))
				param = "?" + param;
		}
		String requestUrl = String.format("%s%s", url, param);
		getMethod = new HttpGet(requestUrl);

		if (headers != null) {
			for (int i = 0; i < headers.size(); ++i) {
				getMethod.setHeader(headers.getKey(i), headers.getValue(i));
			}
		}

		client = AndroidHttpClient.newInstance("");
		HttpParams params = client.getParams();
		params.setParameter(ClientPNames.HANDLE_REDIRECTS, true); // 自动处理重定向


		try {
			HttpResponse response = client.execute(getMethod);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				return false;
			}

			fileSize = response.getEntity().getContentLength();

			ALFileManager.createFile(filePath);

			OutputStream out = new FileOutputStream(filePath);
			InputStream in = response.getEntity().getContent();
			copyFile(out, in, handler);

			if (handler != null) {
				if (isInterrupted)
					handler.handleInterrupted();
				else
					handler.handleResponse(response);
			}

		} catch (IOException e) {
			if (handler != null) {
				handler.handleException(e);
				return false;
			}

		} finally {
			client.close();
		}

		return true;
	}

	public void requestAsync(final IHttpProgressHandler handler) {
		new Thread() {

			@Override
			public void run() {
				request(handler);
			}

		}.start();
	}

	public void cancel() {
		if (isInterrupted)
			return;

		isInterrupted = true;

		if (getMethod != null)
			getMethod.abort();

		if (client != null)
			client.close();
	}

	private void copyFile(OutputStream out, InputStream in,
			IHttpProgressHandler handler) throws IOException {
		byte[] buffer = new byte[BUFFER_SIZE];

		int writeBytes = 0;
		while (!isInterrupted) {
			int readBytes = in.read(buffer, 0, BUFFER_SIZE);
			if (readBytes == -1)
				break;

			out.write(buffer, 0, readBytes);
			writeBytes += readBytes;

			if (handler != null) {
				handler.handleProgress(writeBytes, fileSize);
			}
		}
	}

}
